
var Client = require('ssh2').Client;
var path = require('path')
var conn = new Client()
var fs = require('fs')
var YAML = require('yamljs')
var config = YAML.load('sftp.yaml')
const cliProgress = require('cli-progress');
const siglebar = new cliProgress.SingleBar({
  stopOnComplete: true,
  clearOnComplete: true,
  format: 'progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total} | Speed: {speed} kbit'
}, cliProgress.Presets.shades_classic);

run(config)

async function run (config) {
  let cwd = process.cwd()
  let localePath = config.localePath ? path.join(cwd, config.localePath) : cwd
  let remotePath = config.remotePath
  conn.connect({
    host: config.host,
    username: config.username,
    password: config.password
  })
  await ready(conn)
  let sftp = await connSftp(conn)
  await remoteFiles(localePath, remotePath, '\.git|\/node_modules', sftp, siglebar)
  conn.end()
}

// 链接完成
function ready (conn) {
  return new Promise(resolve => {
    conn.on('ready', () => {
      resolve()
    })
  })
}

// 链接sftp
function connSftp (conn) {
  return new Promise(resolve => {
    conn.sftp(async function(err, sftp) {
      if (err) throw err;
      resolve(sftp)
    });
  })
}

// 文件是否存在
function dirExist (sftp, path) {
  return new Promise (resolve => {
    sftp.exists(path, isExist => {
      resolve(isExist)
    })
  })
}

// 创建文件成功
function mkdir (sftp, path) {
  return new Promise (resolve => {
    sftp.mkdir(path, isMk => {
      resolve(isMk)
    })
  })
}
// 正在上传
function fastPut (sftp, path, tarPath, siglebar) {
  return new Promise(resolve => {
    let startFlag = true
    sftp.fastPut(path, tarPath, {
      step: (total_transferred, chunk, total) => {
        if (startFlag) {
          siglebar.start(total, total_transferred, {
            speed: "N/A"
        });
          startFlag = false
        }
        siglebar.update(total_transferred, {
          speed: chunk/1000
      })
      }
    }, err => {
      if (err) {
        throw err
      }
      resolve()
    })
   }) 
}

// 上传所有文件
async function remoteFiles (sourcePath, rpath, reg, sftp, siglebar) {
  let dir = fs.readdirSync(sourcePath)
  if (await dirExist(sftp, rpath) === false) {
    await mkdir(sftp, rpath)
  }
  for (let i = 0; i < dir.length; i++) {
    let filePath = dir[i]
    let path = `${sourcePath}/${filePath}`
    let stat = fs.statSync(path)
    let tarPath = `${rpath}/${filePath}`
    if (stat.isDirectory()) {
      if (new RegExp(reg).test(path)) continue
     await remoteFiles(path, tarPath, reg, sftp, siglebar)
    } else {
     await fastPut(sftp, path, tarPath, siglebar)
    }
  }
}